package com.sixbro.api.docs.config;

import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;
import springfox.documentation.builders.*;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * <p>
 *  自定义swagger3文档信息
 * </p>
 *
 * @Author: Mr.Lu
 * @Since: 2022/1/5 18:07
 */
//@OpenAPIDefinition(
//        security = @SecurityRequirement(name = "Oauth2"),
//        externalDocs = @ExternalDocumentation(
//                description = "项目编译部署说明",
//                url = "http://localhost/deploy/README.md"
//        )
//)
@Configuration
@EnableConfigurationProperties(Swagger3ConfigurationProperties.class)
@ConditionalOnProperty(value = "springfox.documentation.enabled", havingValue = "true", matchIfMissing = true)
public class Swagger3Configuration {
    @Autowired
    private Swagger3ConfigurationProperties properties;

    /**
     * 后台管理 API
     * @return
     */
    @Bean
    public Docket adminApi(@Value("${springfox.documentation.enabled:true}") Boolean enabled) {
        // OAS_30：区别于 V2，（OpenAPI Specification 的简称 OAS）
        // 使用 OpenAPI 3.0
        return new Docket(DocumentationType.OAS_30)
                .enable(enabled)
                // API 信息
                .apiInfo(apiInfo())
                // API 分组
                .groupName(properties.getApiGroupName())
//                todo 此处还没有搞清楚
//                .servers(
//                        new Server("生产环境服务器", "https://xxxx.com/api/v1", "生产环境服务器", Collections.EMPTY_LIST, null),
//                        new Server("测试环境服务器", "https://test.xxxx.com/api/v1", "测试环境服务器", Collections.EMPTY_LIST, null)
//                )
                .securitySchemes(Collections.singletonList(
                        HttpAuthenticationScheme
                                .JWT_BEARER_BUILDER
                                .name(HttpHeaders.AUTHORIZATION)
                                .description("Bearer Token")
                                .build()
                ))
                .securityContexts(Collections.singletonList(
                        SecurityContext
                                .builder()
                                .securityReferences(Collections.singletonList(
                                        SecurityReference
                                                .builder()
                                                .scopes(new AuthorizationScope[0])
                                                .reference("JWT")
                                                .build()
                                ))
                                // 声明作用域
                                .operationSelector(operationContext -> operationContext.requestMappingPattern().matches("/.*"))
                                .build()
                ))
                .select()
                // 对某个包的接口进行监听
                .apis(StringUtils.hasText(properties.getApiBasePackage()) ? RequestHandlerSelectors.basePackage(properties.getApiBasePackage()) : RequestHandlerSelectors.withMethodAnnotation(Operation.class))
                .paths(StringUtils.hasText(properties.getApiBasePath()) ? PathSelectors.ant(properties.getApiBasePath()) : PathSelectors.any())
                .build();
    }

    /**
     * 构建 api文档的详细信息函数,注意这里的注解引用的是哪个
     *
     * @return
     */
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                // 文档标题
                .title(properties.getApiTitle())
                // 文档描述
                .description(properties.getApiDescription())
                // 用于定义服务的域名【服务条款URL】
                .termsOfServiceUrl(properties.getApiTermsOfServiceUrl())
                // 可以用来定义版本。
                .version(properties.getApiVersion())
                // 链接显示文字
                .license(properties.getApiLicense())
                // 网站链接
                .licenseUrl(properties.getApiLicenseUrl())
                // 联系人信息
                .contact(new Contact(properties.getApiContact().getName(), properties.getApiContact().getEmail(), properties.getApiContact().getUrl()))
                .build();
    }

    /**
     * 生成全局通用参数
     *
     * @return
     */
    private List<RequestParameter> getGlobalRequestParameters() {
        List<RequestParameter> parameters = new ArrayList<>();
        parameters.add(
                new RequestParameterBuilder()
                        .name("Authorization")
                        .description("令牌")
                        .required(false)
                        .in(ParameterType.HEADER)
                        .build()
        );
        return parameters;
    }

    /**
     * 生成通用响应信息
     *
     * @return
     */
    private List<Response> getGlobalResponseMessage() {
        List<Response> responseList = new ArrayList<>();
        responseList.add(new ResponseBuilder().code("404").description("找不到资源").build());
        return responseList;
    }
}

